package org.jeecg.modules.nurse_user_orders.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.constant.rabbitConstant;
import org.jeecg.modules.medication.entity.MedicationShop;
import org.jeecg.modules.medication.service.IMedicationShopService;
import org.jeecg.modules.medication_order.entity.MedicationOrderDetail;
import org.jeecg.modules.night_fee.entity.NightFee;
import org.jeecg.modules.night_fee.service.INightFeeService;
import org.jeecg.modules.nurse_distance.entity.NurseDistance;
import org.jeecg.modules.nurse_distance.service.INurseDistanceService;
import org.jeecg.modules.nurse_expert.entity.NurseExpert;
import org.jeecg.modules.nurse_expert.service.INurseExpertService;
import org.jeecg.modules.nurse_goods.entity.NurseGoods;
import org.jeecg.modules.nurse_goods.mapper.NurseGoodsMapper;
import org.jeecg.modules.nurse_goods_detail.entity.NurseGoodsDetail;
import org.jeecg.modules.nurse_goods_detail.mapper.NurseGoodsDetailMapper;
import org.jeecg.modules.nurse_home_addr.entity.NurseHomeAddr;
import org.jeecg.modules.nurse_home_addr.mapper.NurseHomeAddrMapper;
import org.jeecg.modules.nurse_home_addr.service.INurseHomeAddrService;
import org.jeecg.modules.nurse_hospital.entity.NurseHospital;
import org.jeecg.modules.nurse_hospital.mapper.NurseHospitalMapper;
import org.jeecg.modules.nurse_urgent.entity.NurseUrgent;
import org.jeecg.modules.nurse_urgent.service.INurseUrgentService;
import org.jeecg.modules.nurse_user.entity.*;
import org.jeecg.modules.nurse_user.mapper.*;
import org.jeecg.modules.nurse_user.service.INurseUserIntegralService;
import org.jeecg.modules.nurse_user_bill.entity.NurseUserBill;
import org.jeecg.modules.nurse_user_bill.entity.NurseUserBillDetail;
import org.jeecg.modules.nurse_user_bill.mapper.NurseUserBillDetailMapper;
import org.jeecg.modules.nurse_user_bill.mapper.NurseUserBillMapper;
import org.jeecg.modules.nurse_user_orders.entity.NurseUserOrders;
import org.jeecg.modules.nurse_user_orders.entity.NurseUserOrdersDetail;
import org.jeecg.modules.nurse_user_orders.entity.NurseUserOrdersPre;
import org.jeecg.modules.nurse_user_orders.mapper.NurseUserOrdersDetailMapper;
import org.jeecg.modules.nurse_user_orders.mapper.NurseUserOrdersCommentMapper;
import org.jeecg.modules.nurse_user_orders.mapper.NurseUserOrdersPreMapper;
import org.jeecg.modules.nurse_user_orders.mapper.NurseUserOrdersMapper;
import org.jeecg.modules.nurse_user_orders.service.INurseUserOrdersDetailService;
import org.jeecg.modules.nurse_user_orders.service.INurseUserOrdersService;
import org.jeecg.modules.nurse_user_orders.vo.NurseSpecialVo;
import org.jeecg.modules.nurse_user_orders.vo.NurseUserOrdersDetailsVo;
import org.jeecg.modules.nurse_user_orders.vo.NurseUserOrdersVo;
import org.jeecg.modules.nurse_user_orders_refund.entity.NurseUserOrdersRefund;
import org.jeecg.modules.nurse_user_orders_refund.service.INurseUserOrdersRefundService;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.wechat.service.WechatPaymentService;
import org.jeecg.modules.wechat.utils.WXPaySignatureCertificateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 用户订单
 * @Author: jeecg-boot
 * @Date: 2024-06-04
 * @Version: V1.0
 */
@Service
@Slf4j
public class NurseUserOrdersServiceImpl extends ServiceImpl<NurseUserOrdersMapper, NurseUserOrders> implements INurseUserOrdersService {

    @Autowired
    private NurseUserOrdersMapper nurseUserOrdersMapper;
    @Autowired
    private NurseUserOrdersDetailMapper nurseUserOrdersDetailMapper;

    @Autowired
    private INurseUserOrdersDetailService nurseUserOrdersDetailService;

    @Autowired
    private NurseUserOrdersCommentMapper nurseUserOrdersCommentMapper;

    @Autowired
    private NurseUserOrdersPreMapper nurseUserOrdersPreMapper;

    @Autowired
    private NurseUserAddrMapper nurseUserAddrMapper;

    @Autowired
    private NurseUserFamilyMapper nurseUserFamilyMapper;

    @Autowired
    private NurseUserMapper nurseUserMapper;

    @Autowired
    private NurseGoodsDetailMapper nurseGoodsDetailMapper;

    @Autowired
    private NurseGoodsMapper nurseGoodsMapper;

    @Autowired
    private RabbitMqClient rabbitMqClient;

    @Autowired
    private NurseUserBillMapper nurseUserBillMapper;

    @Autowired
    private NurseUserBillDetailMapper nurseUserBillDetailMapper;

    @Autowired
    private NurseHospitalMapper nurseHospitalMapper;

    @Autowired
    private NurseUserIntegralMapper nurseUserIntegralMapper;

    @Autowired
    private WechatPaymentService wechatPaymentService;

    @Autowired
    private INurseUserOrdersRefundService nurseUserOrdersRefundService;

    @Autowired
    private NurseUserSpecialMapper nurseUserSpecialMapper;

    @Autowired
    private INurseUserIntegralService nurseUserIntegralService;


    @Autowired
    private INurseUrgentService nurseUrgentService;

    @Autowired
    private INurseDistanceService nurseDistanceService;

    @Autowired
    private INurseExpertService nurseExpertService;

    @Autowired
    private INightFeeService nightFeeService;

    @Autowired
    private IMedicationShopService medicationShopService;

    @Autowired
    private NurseHomeAddrMapper nurseHomeAddrMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Autowired
    private RedisUtil redisUtil;

//    @Autowired
//    private NurseWebSocket nurseWebSocket;


    @Value("${wechat.nurse.expiry-time:}")
    private Integer expiryTime;

    /**
     * 重写page方法，使用selectOrdersWithStandard查询
     * @param page 分页对象
     * @param queryWrapper 查询条件
     * @return 分页结果
     */
    @Override
    @SuppressWarnings("unchecked")
    public <E extends IPage<NurseUserOrders>> E page(E page, Wrapper<NurseUserOrders> queryWrapper) {
        IPage<NurseUserOrders> result = nurseUserOrdersMapper.selectOrdersWithStandard(page, queryWrapper);
        return (E) result;
    }

    @Value("${wechat.nurse.appid:}")
    private String APP_ID;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(String id) {
        nurseUserOrdersDetailMapper.deleteByMainId(id);
        nurseUserOrdersCommentMapper.deleteByMainId(id);
        nurseUserOrdersPreMapper.deleteByMainId(id);
        nurseUserOrdersMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            nurseUserOrdersDetailMapper.deleteByMainId(id.toString());
            nurseUserOrdersCommentMapper.deleteByMainId(id.toString());
            nurseUserOrdersPreMapper.deleteByMainId(id.toString());
            nurseUserOrdersMapper.deleteById(id);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseMap addByWeChat(NurseUserOrdersVo nurseUserOrdersVo,String mchId) throws Exception {

        NurseUser nurseUser = nurseUserMapper.selectById(nurseUserOrdersVo.getUserId());
      //  NurseHomeAddr nurseHomeAddr = nurseHomeAddrMapper.selectById(nurseUserOrdersVo.getAddrId());
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(nurseUserOrdersVo.getOrderJson());
        String hospital = jsonNode.get("hospital").asText();
        String hospitalId = jsonNode.get("hospitalId").asText();

        if (nurseUser == null) {
            throw new JeecgBootException("未查询到用户");
        }
        NurseUserFamily nurseUserFamily = nurseUserFamilyMapper.selectById(nurseUserOrdersVo.getFamilyId());
        if (nurseUserFamily == null) {
            throw new JeecgBootException("未查询到用户监护人");
        }
//        if(nurseHomeAddr == null){
//            throw new JeecgBootException("未查询到居家地址");
//        }
        NurseUserAddr nurseUserAddr = nurseUserAddrMapper.selectById(nurseUserOrdersVo.getAddrId());
        NurseUserOrders nurseUserOrder = new NurseUserOrders();
        if (nurseUserAddr == null) {
            throw new JeecgBootException("未查询到默认居家或者院内地址");
        }
        else{
            BeanUtils.copyProperties(nurseUserAddr, nurseUserOrder);
            nurseUserOrder.setAddrId(nurseUserOrdersVo.getAddrId());
            nurseUserOrder.setAddress(nurseUserAddr.getAreaName()+nurseUserAddr.getAddress());
        }
        BaseMap map = new BaseMap();

        String orderId = UUIDGenerator.generate();

        BigDecimal amt = new BigDecimal(0);

        List<NurseUserOrdersDetail> nurseUserOrdersDetailList = new ArrayList<>();

        for (NurseUserOrdersDetailsVo entity : nurseUserOrdersVo.getNurseUserOrdersDetails()) {
            NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();
            NurseGoodsDetail nurseGoodsDetail = nurseGoodsDetailMapper.selectById(entity.getGoodsId());

            if (nurseGoodsDetail == null) {
                throw new JeecgBootException("未查询到商品详情");
            }
            NurseGoods nurseGoods = nurseGoodsMapper.selectById(entity.getGoodsId());

            if (nurseGoods == null) {
                throw new JeecgBootException("未查询到商品信息");
            }
            //规格
         /*   if(oConvertUtils.isNotEmpty(nurseGoodsDetail.getStandardId())){

            }*/

            BeanUtils.copyProperties(nurseGoodsDetail, nurseUserOrdersDetail);
            nurseUserOrdersDetail.setPid(entity.getPid());
            nurseUserOrdersDetail.setPname(entity.getPname());
            nurseUserOrdersDetail.setUnit(nurseGoods.getUnit());
            //nurseUserOrdersDetail.setPrice(nurseGoodsDetail.getPrice());
            nurseUserOrdersDetail.setPrice(entity.getPrice());
            nurseUserOrdersDetail.setNum(entity.getNum());
           // nurseUserOrdersDetail.setAmt(nurseGoodsDetail.getPrice().multiply(new BigDecimal(entity.getNum())));
            nurseUserOrdersDetail.setAmt(entity.getPrice().multiply(new BigDecimal(entity.getNum())));
            nurseUserOrdersDetail.setOrderId(orderId);
            nurseUserOrdersDetail.setId(null);
            nurseUserOrdersDetail.setCreateBy(null);
            nurseUserOrdersDetail.setCreateTime(null);
            nurseUserOrdersDetail.setUpdateBy(null);
            nurseUserOrdersDetail.setUpdateTime(null);

            amt = amt.add(nurseUserOrdersDetail.getAmt());

            nurseUserOrdersDetailList.add(nurseUserOrdersDetail);

        }

        for (NurseSpecialVo entity : nurseUserOrdersVo.getSpecialDetails()) {

            NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();

            QueryWrapper<NurseUserSpecial> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", entity.getId());
            queryWrapper.eq("status", "1");
            queryWrapper.apply("NOW() >= begin_time");
            queryWrapper.apply("NOW() <= end_time");
          //  queryWrapper.apply("CONVERT(VARCHAR (23), getDate(), 120) >= CONVERT(VARCHAR (23), begin_time, 120) ");
          //  queryWrapper.apply("CONVERT(VARCHAR (23), getDate(), 120) <= CONVERT(VARCHAR (23), end_time, 120) ");

            NurseUserSpecial nurseUserSpecial = nurseUserSpecialMapper.selectOne(queryWrapper);

            if (nurseUserSpecial == null) {
                throw new JeecgBootException("未查询到优惠劵信息");
            }
            nurseUserSpecial.setAmt(nurseUserSpecial.getAmt().multiply(new BigDecimal(-1)));

            BeanUtils.copyProperties(nurseUserSpecial, nurseUserOrdersDetail);

            nurseUserOrdersDetail.setPname(nurseUserSpecial.getType());
            nurseUserOrdersDetail.setUnit("张");
            nurseUserOrdersDetail.setPid(nurseUserSpecial.getId());
            nurseUserOrdersDetail.setPrice(nurseUserSpecial.getAmt());
            nurseUserOrdersDetail.setNum(1);
            nurseUserOrdersDetail.setOrderId(orderId);
            nurseUserOrdersDetail.setId(null);
            nurseUserOrdersDetail.setCostType("0");
            nurseUserOrdersDetail.setCostTypeName(nurseUserSpecial.getName());
            nurseUserOrdersDetail.setCreateBy(null);
            nurseUserOrdersDetail.setCreateTime(null);
            nurseUserOrdersDetail.setUpdateBy(null);
            nurseUserOrdersDetail.setUpdateTime(null);

            amt = amt.add(nurseUserOrdersDetail.getAmt());

            nurseUserOrdersDetailList.add(nurseUserOrdersDetail);

        }

        //远程费_old

         if (oConvertUtils.isNotEmpty(nurseUserOrdersVo.getDistanceId())) {
         NurseDistance nurseDistance = nurseDistanceService.getById(nurseUserOrdersVo.getDistanceId());
         if (nurseDistance != null) {
         NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();
         nurseUserOrdersDetail.setPrice(nurseDistance.getFee());
         nurseUserOrdersDetail.setPname("");
         nurseUserOrdersDetail.setGoodsId(nurseDistance.getId());
         nurseUserOrdersDetail.setGoodsName(nurseDistance.getName());
         nurseUserOrdersDetail.setUnit("次");
         nurseUserOrdersDetail.setPid("1");

         nurseUserOrdersDetail.setNum(1);
        if(oConvertUtils.isNotEmpty(nurseUserOrdersVo.getDistanceNum()))
        { nurseUserOrdersDetail.setNum(nurseUserOrdersVo.getDistanceNum());
        }  ;
        nurseUserOrdersDetail.setAmt(nurseDistance.getFee().multiply(BigDecimal.valueOf(nurseUserOrdersVo.getDistanceNum())));
         nurseUserOrdersDetail.setOrderId(orderId);
         nurseUserOrdersDetail.setId(null);
         nurseUserOrdersDetail.setCostType("0");
         nurseUserOrdersDetail.setCostTypeName(nurseDistance.getName());
         nurseUserOrdersDetail.setCreateBy(null);
         nurseUserOrdersDetail.setCreateTime(null);
         nurseUserOrdersDetail.setUpdateBy(null);
         nurseUserOrdersDetail.setUpdateTime(null);
         nurseUserOrdersDetail.setAmt(nurseUserOrdersVo.getDistanceFee());
         nurseUserOrdersDetail.setNum(nurseUserOrdersVo.getDistanceFee().divide(nurseDistance.getFee()).intValue());

         amt = amt.add(nurseUserOrdersDetail.getAmt());
         nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
         }
         }

        //远程费_new
    /*    List<NurseDistance> nurseDistanceList = nurseDistanceService.getByAddrIdAndHospitalId(nurseUserAddr.getId(), nurseUserOrder.getHospital());
            for (NurseDistance nurseDistanceEntity : nurseDistanceList) {
                NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();

                nurseUserOrdersDetail.setAmt(nurseDistanceEntity.getFee());
                nurseUserOrdersDetail.setPname("");
                nurseUserOrdersDetail.setGoodsId(nurseDistanceEntity.getId());
                nurseUserOrdersDetail.setGoodsName(nurseDistanceEntity.getName());
                nurseUserOrdersDetail.setUnit("次");
                nurseUserOrdersDetail.setPid("1");
                nurseUserOrdersDetail.setPrice(nurseDistanceEntity.getFee());
                nurseUserOrdersDetail.setNum(1);
                nurseUserOrdersDetail.setOrderId(orderId);
                nurseUserOrdersDetail.setId(null);
                nurseUserOrdersDetail.setCostType("0");
                nurseUserOrdersDetail.setCostTypeName(nurseDistanceEntity.getName());
                nurseUserOrdersDetail.setCreateBy(null);
                nurseUserOrdersDetail.setCreateTime(null);
                nurseUserOrdersDetail.setUpdateBy(null);
                nurseUserOrdersDetail.setUpdateTime(null);

                amt = amt.add(nurseUserOrdersDetail.getAmt());

                nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
            }*/

        //专家费
        if (oConvertUtils.isNotEmpty(nurseUserOrdersVo.getExpertId())) {

            NurseExpert nurseExpert = nurseExpertService.getById(nurseUserOrdersVo.getExpertId());

            if (nurseExpert != null) {
                NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();


                nurseUserOrdersDetail.setPname("");
                nurseUserOrdersDetail.setGoodsId(nurseExpert.getId());
                nurseUserOrdersDetail.setGoodsName(nurseExpert.getName());
                nurseUserOrdersDetail.setUnit("次");
                nurseUserOrdersDetail.setPid("2");
                nurseUserOrdersDetail.setPrice(nurseExpert.getFee());
                //nurseUserOrdersDetail.setNum(1);
                if(oConvertUtils.isNotEmpty(nurseUserOrdersVo.getExpertNum()))
                { nurseUserOrdersDetail.setNum(nurseUserOrdersVo.getExpertNum());
                }  ;
                nurseUserOrdersDetail.setAmt(nurseExpert.getFee().multiply(BigDecimal.valueOf(nurseUserOrdersVo.getExpertNum())));
                nurseUserOrdersDetail.setPrice(nurseExpert.getFee());
                nurseUserOrdersDetail.setOrderId(orderId);
                nurseUserOrdersDetail.setId(null);
                nurseUserOrdersDetail.setCostType("0");
                nurseUserOrdersDetail.setCostTypeName(nurseExpert.getName());
                nurseUserOrdersDetail.setCreateBy(null);
                nurseUserOrdersDetail.setCreateTime(null);
                nurseUserOrdersDetail.setUpdateBy(null);
                nurseUserOrdersDetail.setUpdateTime(null);
                nurseUserOrdersDetail.setAmt(nurseUserOrdersVo.getExpertFee());
                nurseUserOrdersDetail.setNum(
                        nurseExpert.getFee().compareTo(BigDecimal.ZERO) == 0
                                ? 1
                                : nurseUserOrdersVo.getExpertFee().divide(nurseExpert.getFee()).intValue()
                );
                amt = amt.add(nurseUserOrdersDetail.getAmt());

                nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
            }
        }


        //加急费
        if (oConvertUtils.isNotEmpty(nurseUserOrdersVo.getUrgentId())) {

            NurseUrgent nurseUrgent = nurseUrgentService.getById(nurseUserOrdersVo.getUrgentId());

            if (nurseUrgent != null) {
                NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();

                nurseUserOrdersDetail.setAmt(nurseUrgent.getFee());
                nurseUserOrdersDetail.setPname("");
                nurseUserOrdersDetail.setGoodsId(nurseUrgent.getId());
                nurseUserOrdersDetail.setGoodsName(nurseUrgent.getName());
                nurseUserOrdersDetail.setUnit("次");
                nurseUserOrdersDetail.setPid("3");
                nurseUserOrdersDetail.setPrice(nurseUrgent.getFee());
                nurseUserOrdersDetail.setNum(1);
                nurseUserOrdersDetail.setOrderId(orderId);
                nurseUserOrdersDetail.setId(null);
                nurseUserOrdersDetail.setCostType("0");
                nurseUserOrdersDetail.setCostTypeName(nurseUrgent.getName());
                nurseUserOrdersDetail.setCreateBy(null);
                nurseUserOrdersDetail.setCreateTime(null);
                nurseUserOrdersDetail.setUpdateBy(null);
                nurseUserOrdersDetail.setUpdateTime(null);

                amt = amt.add(nurseUserOrdersDetail.getAmt());

                nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
            }
        }

        //夜班
        if (oConvertUtils.isNotEmpty(nurseUserOrdersVo.getNightId())) {

            NightFee nightFee = nightFeeService.getById(nurseUserOrdersVo.getNightId());

            if (nightFee != null) {
                NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();

                nurseUserOrdersDetail.setAmt(nightFee.getFee());
                nurseUserOrdersDetail.setPname("");
                nurseUserOrdersDetail.setGoodsId(nightFee.getId());
                nurseUserOrdersDetail.setGoodsName(nightFee.getName());
                nurseUserOrdersDetail.setUnit("次");
               // nurseUserOrdersDetail.setPid("3");
                nurseUserOrdersDetail.setPrice(nightFee.getFee());
                nurseUserOrdersDetail.setNum(1);
                nurseUserOrdersDetail.setOrderId(orderId);
                nurseUserOrdersDetail.setId(null);
                nurseUserOrdersDetail.setCostType("0");
                nurseUserOrdersDetail.setCostTypeName(nightFee.getName());
                nurseUserOrdersDetail.setCreateBy(null);
                nurseUserOrdersDetail.setCreateTime(null);
                nurseUserOrdersDetail.setUpdateBy(null);
                nurseUserOrdersDetail.setUpdateTime(null);

                amt = amt.add(nurseUserOrdersDetail.getAmt());

                nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
            }
        }
             //添加商品
        if (oConvertUtils.isNotEmpty(nurseUserOrdersVo.getMedicationOrderDetails())) {
            for (MedicationOrderDetail medicationdetail : nurseUserOrdersVo.getMedicationOrderDetails()) {
                MedicationShop medicationShop = medicationShopService.getById(medicationdetail.getGoodsId());
                if (medicationShop == null) {
                    throw new JeecgBootException("未查询到药房商品信息");
                }
                NurseUserOrdersDetail nurseUserOrdersDetail = new NurseUserOrdersDetail();
                nurseUserOrdersDetail.setAmt(medicationShop.getPrice().multiply(new BigDecimal(medicationdetail.getNum())));
                nurseUserOrdersDetail.setPname("");
                nurseUserOrdersDetail.setGoodsId(medicationShop.getId());
                nurseUserOrdersDetail.setGoodsName(medicationdetail.getGoodsName());
                nurseUserOrdersDetail.setUnit(medicationShop.getUnit());
                // nurseUserOrdersDetail.setPid("3");
                nurseUserOrdersDetail.setPrice(medicationShop.getPrice());
                nurseUserOrdersDetail.setNum(medicationdetail.getNum().intValue());
                nurseUserOrdersDetail.setOrderId(orderId);
                nurseUserOrdersDetail.setId(null);
                nurseUserOrdersDetail.setCostType("0");
                nurseUserOrdersDetail.setCostTypeName(medicationdetail.getGoodsName());
                nurseUserOrdersDetail.setCreateBy(null);
                nurseUserOrdersDetail.setCreateTime(null);
                nurseUserOrdersDetail.setUpdateBy(null);
                nurseUserOrdersDetail.setUpdateTime(null);

                amt = amt.add(nurseUserOrdersDetail.getAmt());

                nurseUserOrdersDetailList.add(nurseUserOrdersDetail);
            }
        }


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        nurseUserOrder.setNurseType(nurseUserOrdersVo.getNurseType());
        nurseUserOrder.setRemark(nurseUserOrdersVo.getRemark());
        nurseUserOrder.setOrderText(nurseUserOrdersVo.getOrderText());
        nurseUserOrder.setBeginDate(DateUtils.str2Date(nurseUserOrdersVo.getBeginDate(), sdf));
        nurseUserOrder.setEndDate(DateUtils.str2Date(nurseUserOrdersVo.getEndDate(), sdf));
        nurseUserOrder.setCreateTime(DateUtils.getDate());
        //nurseUserOrder.setContacts(nurseUserAddr.getName());
        nurseUserOrder.setUserId(nurseUser.getId());
        nurseUserOrder.setOpenid(nurseUser.getOpenid());
        nurseUserOrder.setUserName(nurseUser.getName());
        nurseUserOrder.setFamilyId(nurseUserOrdersVo.getFamilyId());
        nurseUserOrder.setFamilyName(nurseUserFamily.getName());
        nurseUserOrder.setId(orderId);
        nurseUserOrder.setCode(orderId);
        nurseUserOrder.setStatus("1");
        nurseUserOrder.setDispense("1");
        nurseUserOrder.setAmt(amt);
        nurseUserOrder.setOutTradeNo(orderId);
        nurseUserOrder.setIsGoHome(nurseUserOrdersVo.getIsGoHome());
        nurseUserOrder.setUrgentId(nurseUserOrdersVo.getUrgentId());
        nurseUserOrder.setUrgentName(nurseUserOrdersVo.getUrgentName());
        nurseUserOrder.setDistance(nurseUserOrdersVo.getDistance());
        nurseUserOrder.setDistanceFee(nurseUserOrdersVo.getDistanceFee());
        nurseUserOrder.setExpertId(nurseUserOrdersVo.getExpertId());
        nurseUserOrder.setExpertName(nurseUserOrdersVo.getExpertName());
        nurseUserOrder.setIsPickup(nurseUserOrdersVo.getIsPickup());
        nurseUserOrder.setIsFestival(nurseUserOrdersVo.getIsFestival());
        nurseUserOrder.setNightId(nurseUserOrdersVo.getNightId());
        nurseUserOrder.setNightName(nurseUserOrdersVo.getNightName());
        nurseUserOrder.setOrderJson(nurseUserOrdersVo.getOrderJson());
        nurseUserOrder.setStandardId(nurseUserOrdersVo.getStandardId());
        nurseUserOrder.setMchid(mchId);
        nurseUserOrder.setSysOrgCode(nurseUserOrdersVo.getSysOrgCode());

        Integer expiry_time = 1000 * expiryTime;

        nurseUserOrder.setExpiryTime(DateUtils.getDate(nurseUserOrder.getCreateTime().getTime() + 1000L * 365 * 24 * 60 * 60 * 1000));

        nurseUserOrder.setCreateBy("admin");
        nurseUserOrder.setUpdateBy("admin");
        nurseUserOrder.setUpdateTime(DateUtils.getDate());
       // nurseUserOrder.setAmt(nurseUserOrdersVo.getPreAmt());
        nurseUserOrder.setAmt(nurseUserOrdersVo.getTotalPrice());
        nurseUserOrder.setHospital(hospitalId);
        nurseUserOrder.setHospitalName(hospital);
        nurseUserOrder.setPhone(nurseUser.getPhone());
        nurseUserOrder.setIdcard(nurseUser.getIdcard());

        Long total = nurseUserOrder.getAmt().multiply(BigDecimal.valueOf(100)).longValue();

        map.put("total", total);
        map.put("description", nurseUserOrder.getOrderText());
        map.put("out_trade_no", nurseUserOrder.getOutTradeNo());
        map.put("openid", nurseUserOrder.getOpenid());
        map.put("org",nurseUserOrder.getSysOrgCode());

        try {
            map = wechatPaymentService.weChatDoUnifiedOrder(map,mchId);

        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!map.get("code").equals(200)) {
            throw new JeecgBootException("微信下单失败！" + map.toString());
        }

        nurseUserOrder.setPrepayid(map.get("prepayid"));

        nurseUserOrdersMapper.insert(nurseUserOrder);

        nurseUserOrdersDetailService.saveBatch(nurseUserOrdersDetailList);

        if (nurseUserOrdersVo.getPreAmt() != null && nurseUserOrdersVo.getPreAmt().compareTo(BigDecimal.ZERO) > 0) {
            NurseUserOrdersPre nurseUserOrdersPre = new NurseUserOrdersPre();
            nurseUserOrdersPre.setAmt(nurseUserOrdersVo.getPreAmt());
            nurseUserOrdersPre.setOrderId(orderId);
            nurseUserOrdersPre.setPrice(nurseUserOrdersVo.getPreAmt());
            nurseUserOrdersPre.setNum(1);
            nurseUserOrdersPre.setStatus("1");
            nurseUserOrdersPre.setGoodsId("预付款");
            nurseUserOrdersPre.setGoodsName("预付款");
            nurseUserOrdersPreMapper.insert(nurseUserOrdersPre);
        }

        map.put("out_trade_no", orderId);

        // 注释掉延迟队列处理逻辑，取消自动过期处理
        // rabbitMqClient.sendMessage(rabbitConstant.DELAY_QUEUE_ORDER_NAME, map, expiry_time);

        log.info("订单编号：[{}] 创建完成，已取消延迟队列过期处理", orderId);

        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<NurseUserOrders> checkOrderStatus(String orderId) {

        List<NurseUserOrders>nurseUserOrder = nurseUserOrdersMapper.selectList(new QueryWrapper<NurseUserOrders>().eq("out_trade_no", orderId));

        if (nurseUserOrder.isEmpty()) {
            return null;
        }

        String status = nurseUserOrder.get(0).getStatus();

        if (status.equals("3") || status.equals("7") || status.equals("8")) {
            return null;
        }
        String refundnum = UUIDGenerator.generate();
              for(NurseUserOrders order: nurseUserOrder){
                  order.setStatus("7");
                  order.setRefundTime(DateUtils.getDate());
                  order.setRefundNumber(refundnum);
                  nurseUserOrdersMapper.updateById(order);
        }

       NurseUserOrdersRefund nurseUserOrdersRefund = nurseUserOrdersRefundService.getById(orderId);
       if (nurseUserOrdersRefund != null) {
          nurseUserOrdersRefund.setStatus("7");
          nurseUserOrdersRefundService.updateById(nurseUserOrdersRefund);
          nurseUserIntegralService.deleteByOrderId(orderId);
           }
        return nurseUserOrder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<NurseUserOrders> checkOrderStatus1(String orderId) {

        List<NurseUserOrders>nurseUserOrder = nurseUserOrdersMapper.selectList(new QueryWrapper<NurseUserOrders>().eq("out_trade_no", orderId));

        if (nurseUserOrder.isEmpty()) {
            return null;
        }

        String status = nurseUserOrder.get(0).getStatus();
       //待付款可以取消
        if (!status.equals("1") ) {
            return null;
        }
        for(NurseUserOrders order: nurseUserOrder){
            order.setStatus("3");
            order.setCancelTime(DateUtils.getDate());
            nurseUserOrdersMapper.updateById(order);
        }

        return nurseUserOrder;
    }

    @Override
    public List<Map<String, Object>> listByWeChat(String beginDate, String endDate, String nurseType, String userId, String status) {
        return nurseUserOrdersMapper.listByWeChat(beginDate, endDate, nurseType, userId, status);
    }

    @Override
    public void closeByWeChat(String id) {
        List<NurseUserOrders> nurseUserOrder = checkOrderStatus1(id);

        if (nurseUserOrder == null) {
            throw new JeecgBootException("取消订单失败！");
        }

    }

    @Override
    public NurseUserOrders successPay(NurseUserOrders nurseUserOrder) {

        List<NurseUserOrdersDetail> nurseUserOrdersDetails = nurseUserOrdersDetailMapper.selectList(new QueryWrapper<NurseUserOrdersDetail>().eq("order_id", nurseUserOrder.getId()));

        if (nurseUserOrdersDetails == null) {
            return null;
        }
        if (nurseUserOrdersDetails.size() == 0) {
            return null;
        }

        String billCode = null;

        NurseHospital nurseHospital = nurseHospitalMapper.selectById(nurseUserOrder.getHospital());

        if (nurseHospital != null) {
            billCode = nurseHospital.getBillCode();
        }

        NurseUserBill nurseUserBill = new NurseUserBill();

        BeanUtils.copyProperties(nurseUserOrder, nurseUserBill);

        BigDecimal amt = nurseUserOrdersDetails.stream().map(e -> e.getAmt()).reduce(BigDecimal.ZERO, BigDecimal::add);

        nurseUserBill.setBillCode(billCode);
        nurseUserBill.setAmt(amt);
        nurseUserBill.setOrderId(nurseUserOrder.getId());
        nurseUserBill.setId(null);
        nurseUserBill.setCreateBy(nurseUserOrder.getUserId());
        nurseUserBill.setCreateTime(DateUtils.getDate());
        nurseUserBill.setUpdateBy(null);
        nurseUserBill.setUpdateTime(null);

        nurseUserBillMapper.insert(nurseUserBill);

        NurseUserBillDetail nurseUserBillDetail;

        for (NurseUserOrdersDetail entity : nurseUserOrdersDetails) {
            nurseUserBillDetail = new NurseUserBillDetail();
            BeanUtils.copyProperties(entity, nurseUserBillDetail);
            nurseUserBillDetail.setBillId(nurseUserBill.getId());
            nurseUserBillDetail.setId(null);
            nurseUserBillDetailMapper.insert(nurseUserBillDetail);
        }

        nurseUserOrder.setStatus("2");
        nurseUserOrder.setCheckoutTime(DateUtils.getDate());

        nurseUserOrdersMapper.updateById(nurseUserOrder);

        NurseUserIntegral nurseUserIntegral = new NurseUserIntegral();
        nurseUserIntegral.setUserId(nurseUserOrder.getUserId());
        nurseUserIntegral.setOrderId(nurseUserOrder.getId());
        nurseUserIntegral.setAmt(amt);
        nurseUserIntegral.setCreateBy(nurseUserOrder.getUserId());
        nurseUserIntegral.setStatus("1");
        nurseUserIntegral.setBeginTime(DateUtils.getDate());

        Calendar calendar = DateUtils.getCalendar();
        calendar.add(Calendar.YEAR, 1);
        nurseUserIntegral.setEndTime(DateUtils.getDate(calendar.getTimeInMillis()));

        nurseUserIntegralMapper.insert(nurseUserIntegral);

//        JSONObject jsonObject = new JSONObject();
//
//        jsonObject.put("msg", "newOrder");

        redisUtil.set("newOrder", DateUtils.getTimestamp());
//        nurseWebSocket.sendAllMessage(jsonObject.toJSONString());
        return nurseUserOrder;
    }

    @Override
    public BaseMap payByWeChat(String out_trade_no) {

        BaseMap map = new BaseMap();

        NurseUserOrders nurseUserOrder = nurseUserOrdersMapper.selectById(out_trade_no);

        if (oConvertUtils.isEmpty(nurseUserOrder)) {
            throw new JeecgBootException("未查询到订单");
        }
        if (!nurseUserOrder.getStatus().equals("1")) {
            throw new JeecgBootException("未查询到待支付订单");
        }

        try {
            map.put("prepayid", nurseUserOrder.getPrepayid());
            map.put("mchId", nurseUserOrder.getMchid());
            map = WXPaySignatureCertificateUtil.jsApiPay(map, APP_ID);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    @Override
    public BaseMap refund(String out_trade_no) {

        BaseMap map = new BaseMap();

        NurseUserOrders nurseUserOrder = nurseUserOrdersMapper.selectById(out_trade_no);

        if (oConvertUtils.isEmpty(nurseUserOrder)) {
            throw new JeecgBootException("未查询到订单");
        }

        if (!nurseUserOrder.getStatus().equals("8")) {
            throw new JeecgBootException("未查询到需要退款订单");
        }

        Long total = nurseUserOrder.getAmt().multiply(BigDecimal.valueOf(100)).longValue();

        String out_refund_no = UUIDGenerator.generate();

        map.put("out_trade_no", out_trade_no);
        map.put("out_refund_no", out_refund_no);
        map.put("total", total);

        map = wechatPaymentService.weChatRefunds(map,nurseUserOrder.getMchid());

        if (map.get("code").equals(200)) {
            nurseUserOrder.setRefundNumber(out_refund_no);
            nurseUserOrder.setStatus("5");
            nurseUserOrder.setRefundTime(DateUtils.getDate());

            map.put("status", "5");

            nurseUserOrdersMapper.updateById(nurseUserOrder);

            Integer expiry_time = 1000 * expiryTime;

            rabbitMqClient.sendMessage(rabbitConstant.DELAY_QUEUE_ORDER_NAME, map, expiry_time);

            log.info("订单编号：[{}] 进入退款延迟队列...", out_trade_no);

        } else {
            throw new JeecgBootException("申请退款失败！");
        }
        return map;
    }

    @Override
    public void payNotify(HttpServletRequest request,String mchid) {

        BaseMap map = wechatPaymentService.weChatNotificationHandler(request,mchid);

        if (!map.get("code").equals(200)) {
            return;
        }
        NurseUserOrders nurseUserOrder = nurseUserOrdersMapper.selectById(map.get("out_trade_no"));

        if (oConvertUtils.isEmpty(nurseUserOrder)) {
            return;
        }

        if (nurseUserOrder.getStatus().equals("2") || nurseUserOrder.getStatus().equals("3")) {
            return;
        }
        successPay(nurseUserOrder);
    }

    @Override
    public BaseMap refundNotify(HttpServletRequest request,String mchid) {

        BaseMap map = wechatPaymentService.weChatPayRefundsNotify(request,mchid);

        if (!map.get("code").equals(200)) {
            return map;
        }

        checkOrderStatus(map.get("out_trade_no"));

        return map;
    }

    @Override
    public void sendOrderNotification(String orgCode, String orderText) {
        try {
            if (oConvertUtils.isEmpty(orgCode)) {
                log.warn("组织代码为空，无法发送订单通知");
                return;
            }
            // 3. 批量查询用户获取username
        List<SysUser> users  = sysUserService.list(new QueryWrapper<SysUser>().eq("org_code", orgCode));
            List<String> usernames = users.stream()
                    .map(SysUser::getUsername)
                    .filter(username -> oConvertUtils.isNotEmpty(username))
                    .distinct()
                    .collect(Collectors.toList());

            if (usernames.isEmpty()) {
                log.warn("未找到有效的用户?");
                return;
            }

            // 4. 为每个用户发送
            String taskName = "有新订单，请尽快审核！";
            for (String username : usernames) {
                try {
                    // 构建消息DTO
                    MessageDTO message = new MessageDTO();
                    message.setType("system");
                    message.setToUser(username);
                    message.setToAll(false);
                    message.setTitle(taskName);
                    message.setTemplateCode("SYS001");

                    // 设置模板变量数据
                    Map<String, Object> data = new HashMap<>();
                    data.put("userName", username);
                    data.put("taskName", taskName);
                    message.setData(data);

                    // 调用消息发送
                    sysBaseAPI.sendTemplateMessage(message);
                    log.info("订单通知消息发送成功，接收{}", username);
                } catch (Exception e) {
                    log.error("发送订单通知消息失败，接收 {}, 错误: {}", username, e.getMessage(), e);
                }
            }

        } catch (Exception e) {
            log.error("发送订单通知消息异常: {}", e.getMessage(), e);
        }
    }

}
